package database

import (
	"database/sql"
	"encoding/json"
	"fmt"
	"os"
	"path/filepath"
	"time"

	"anders-cli/pkg/logger"

	_ "github.com/mattn/go-sqlite3"
)

// DB 数据库连接
var DB *sql.DB

// Project 项目结构体
type Project struct {
	ID          int       `json:"id"`
	Name        string    `json:"name"`
	CreatedAt   time.Time `json:"created_at"`
	State       string    `json:"state"` // JSON字符串存储状态
	Description string    `json:"description,omitempty"`
}

// Task 任务结构体
type Task struct {
	ID        int       `json:"id"`
	ProjectID int       `json:"project_id"`
	TaskID    string    `json:"task_id"`
	AgentRole string    `json:"agent_role"`
	Status    string    `json:"status"`
	Log       string    `json:"log"` // JSON字符串存储日志
	Progress  int       `json:"progress"`
	UpdatedAt time.Time `json:"updated_at"`
}

// ProjectState 项目状态
type ProjectState struct {
	Mode           string                 `json:"mode"`            // "expert" or "team"
	Context        map[string]interface{} `json:"context"`         // AI上下文
	TaskLogs       []string               `json:"task_logs"`       // 任务日志列表
	GanttTasks     []GanttTask            `json:"gantt_tasks"`     // Gantt图任务
	LastTask       string                 `json:"last_task"`       // 最后任务
	LastResponse   string                 `json:"last_response"`   // 最后响应
	LastConfidence int                    `json:"last_confidence"` // 最后置信度
	LastFeedback   string                 `json:"last_feedback"`   // 最后反馈
}

// GanttTask Gantt图任务
type GanttTask struct {
	ID        string     `json:"id"`
	Name      string     `json:"name"`
	AgentRole string     `json:"agent_role"`
	Status    string     `json:"status"`
	Progress  int        `json:"progress"`
	StartTime time.Time  `json:"start_time"`
	EndTime   *time.Time `json:"end_time,omitempty"`
}

// InitDB 初始化数据库
func InitDB() error {
	logger.Info("开始初始化项目数据库")

	// 创建数据目录
	dataDir := filepath.Join(os.Getenv("HOME"), ".anders-cli")
	if err := os.MkdirAll(dataDir, 0755); err != nil {
		logger.Error("创建数据目录失败: %v", err)
		return fmt.Errorf("创建数据目录失败: %v", err)
	}

	// 数据库文件路径
	dbPath := filepath.Join(dataDir, "projects.db")

	// 打开数据库连接
	var err error
	DB, err = sql.Open("sqlite3", dbPath)
	if err != nil {
		logger.Error("打开数据库失败: %v", err)
		return fmt.Errorf("打开数据库失败: %v", err)
	}

	// 测试连接
	if err := DB.Ping(); err != nil {
		logger.Error("数据库连接测试失败: %v", err)
		return fmt.Errorf("数据库连接测试失败: %v", err)
	}

	logger.Info("数据库连接成功，路径: %s", dbPath)

	// 创建表
	if err := createTables(); err != nil {
		logger.Error("创建表失败: %v", err)
		return fmt.Errorf("创建表失败: %v", err)
	}

	logger.Info("项目数据库初始化完成")
	return nil
}

// createTables 创建数据库表
func createTables() error {
	// 创建projects表
	projectSQL := `
	CREATE TABLE IF NOT EXISTS projects (
		id INTEGER PRIMARY KEY AUTOINCREMENT,
		name TEXT UNIQUE NOT NULL,
		created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
		state TEXT,
		description TEXT
	)`

	if _, err := DB.Exec(projectSQL); err != nil {
		logger.Error("创建projects表失败: %v", err)
		return fmt.Errorf("创建projects表失败: %v", err)
	}

	// 创建tasks表
	taskSQL := `
	CREATE TABLE IF NOT EXISTS tasks (
		id INTEGER PRIMARY KEY AUTOINCREMENT,
		project_id INTEGER NOT NULL,
		task_id TEXT NOT NULL,
		agent_role TEXT NOT NULL,
		status TEXT DEFAULT 'pending',
		log TEXT,
		progress INTEGER DEFAULT 0,
		updated_at DATETIME DEFAULT CURRENT_TIMESTAMP,
		FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE
	)`

	if _, err := DB.Exec(taskSQL); err != nil {
		logger.Error("创建tasks表失败: %v", err)
		return fmt.Errorf("创建tasks表失败: %v", err)
	}

	// 创建索引
	indexSQL := `
	CREATE INDEX IF NOT EXISTS idx_projects_name ON projects(name);
	CREATE INDEX IF NOT EXISTS idx_tasks_project_id ON tasks(project_id);
	CREATE INDEX IF NOT EXISTS idx_tasks_status ON tasks(status);
	`

	if _, err := DB.Exec(indexSQL); err != nil {
		logger.Error("创建索引失败: %v", err)
		return fmt.Errorf("创建索引失败: %v", err)
	}

	logger.Info("数据库表和索引创建完成")
	return nil
}

// CloseDB 关闭数据库连接
func CloseDB() {
	if DB != nil {
		DB.Close()
		logger.Info("数据库连接已关闭")
	}
}

// CreateProject 创建新项目
func CreateProject(name, description string) (*Project, error) {
	logger.Info("创建新项目: %s", name)

	// 检查项目是否已存在
	existing, err := GetProjectByName(name)
	if err != nil {
		logger.Error("检查项目存在性失败: %v", err)
		return nil, err
	}
	if existing != nil {
		logger.Warn("项目已存在: %s", name)
		return nil, fmt.Errorf("项目 '%s' 已存在", name)
	}

	// 初始化项目状态
	initialState := ProjectState{
		Mode:       "expert",
		Context:    make(map[string]interface{}),
		TaskLogs:   make([]string, 0),
		GanttTasks: make([]GanttTask, 0),
	}

	stateJSON, err := json.Marshal(initialState)
	if err != nil {
		logger.Error("序列化初始状态失败: %v", err)
		return nil, err
	}

	// 插入项目
	result, err := DB.Exec(
		"INSERT INTO projects (name, description, state) VALUES (?, ?, ?)",
		name, description, string(stateJSON),
	)
	if err != nil {
		logger.Error("插入项目失败: %v", err)
		return nil, err
	}

	id, err := result.LastInsertId()
	if err != nil {
		logger.Error("获取项目ID失败: %v", err)
		return nil, err
	}

	project := &Project{
		ID:          int(id),
		Name:        name,
		CreatedAt:   time.Now(),
		State:       string(stateJSON),
		Description: description,
	}

	logger.Info("项目创建成功: %s (ID: %d)", name, id)
	return project, nil
}

// GetProjectByName 根据名称获取项目
func GetProjectByName(name string) (*Project, error) {
	row := DB.QueryRow("SELECT id, name, created_at, state, description FROM projects WHERE name = ?", name)

	var project Project
	var createdAtStr string
	err := row.Scan(&project.ID, &project.Name, &createdAtStr, &project.State, &project.Description)
	if err != nil {
		if err == sql.ErrNoRows {
			return nil, nil // 项目不存在
		}
		logger.Error("查询项目失败: %v", err)
		return nil, err
	}

	// 解析时间
	project.CreatedAt, err = time.Parse("2006-01-02 15:04:05", createdAtStr)
	if err != nil {
		logger.Warn("解析项目创建时间失败: %v", err)
		project.CreatedAt = time.Now()
	}

	return &project, nil
}

// ListProjects 列出所有项目
func ListProjects() ([]*Project, error) {
	rows, err := DB.Query("SELECT id, name, created_at, state, description FROM projects ORDER BY created_at DESC")
	if err != nil {
		logger.Error("查询项目列表失败: %v", err)
		return nil, err
	}
	defer rows.Close()

	var projects []*Project
	for rows.Next() {
		var project Project
		var createdAtStr string
		err := rows.Scan(&project.ID, &project.Name, &createdAtStr, &project.State, &project.Description)
		if err != nil {
			logger.Error("扫描项目行失败: %v", err)
			continue
		}

		// 解析时间
		project.CreatedAt, err = time.Parse("2006-01-02 15:04:05", createdAtStr)
		if err != nil {
			logger.Warn("解析项目创建时间失败: %v", err)
			project.CreatedAt = time.Now()
		}

		projects = append(projects, &project)
	}

	logger.Info("成功查询到 %d 个项目", len(projects))
	return projects, nil
}

// UpdateProjectState 更新项目状态
func UpdateProjectState(projectName string, state interface{}) error {
	logger.Info("更新项目状态: %s", projectName)

	stateJSON, err := json.Marshal(state)
	if err != nil {
		logger.Error("序列化项目状态失败: %v", err)
		return fmt.Errorf("序列化项目状态失败: %v", err)
	}

	result, err := DB.Exec(
		"UPDATE projects SET state = ? WHERE name = ?",
		string(stateJSON), projectName,
	)
	if err != nil {
		logger.Error("更新项目状态失败: %v", err)
		return fmt.Errorf("更新项目状态失败: %v", err)
	}

	rowsAffected, err := result.RowsAffected()
	if err != nil {
		logger.Error("获取影响行数失败: %v", err)
		return err
	}

	if rowsAffected == 0 {
		logger.Warn("项目不存在: %s", projectName)
		return fmt.Errorf("项目 '%s' 不存在", projectName)
	}

	logger.Info("项目状态更新成功: %s", projectName)
	return nil
}

// CreateTask 创建任务
func CreateTask(projectID int, taskID, agentRole, status string, progress int) (*Task, error) {
	logger.Info("创建任务: projectID=%d, taskID=%s, agentRole=%s", projectID, taskID, agentRole)

	result, err := DB.Exec(
		`INSERT INTO tasks (project_id, task_id, agent_role, status, progress)
		 VALUES (?, ?, ?, ?, ?)`,
		projectID, taskID, agentRole, status, progress,
	)
	if err != nil {
		logger.Error("插入任务失败: %v", err)
		return nil, fmt.Errorf("插入任务失败: %v", err)
	}

	id, err := result.LastInsertId()
	if err != nil {
		logger.Error("获取任务ID失败: %v", err)
		return nil, err
	}

	task := &Task{
		ID:        int(id),
		ProjectID: projectID,
		TaskID:    taskID,
		AgentRole: agentRole,
		Status:    status,
		Log:       "",
		Progress:  progress,
		UpdatedAt: time.Now(),
	}

	logger.Info("任务创建成功: ID=%d", id)
	return task, nil
}

// GetTasksByProject 获取项目的所有任务
func GetTasksByProject(projectID int) ([]*Task, error) {
	rows, err := DB.Query(
		"SELECT id, project_id, task_id, agent_role, status, log, progress, updated_at FROM tasks WHERE project_id = ? ORDER BY updated_at ASC",
		projectID,
	)
	if err != nil {
		logger.Error("查询项目任务失败: %v", err)
		return nil, err
	}
	defer rows.Close()

	var tasks []*Task
	for rows.Next() {
		var task Task
		var updatedAtStr string
		err := rows.Scan(
			&task.ID, &task.ProjectID, &task.TaskID, &task.AgentRole,
			&task.Status, &task.Log, &task.Progress, &updatedAtStr,
		)
		if err != nil {
			logger.Error("扫描任务行失败: %v", err)
			continue
		}

		// 解析时间
		task.UpdatedAt, err = time.Parse("2006-01-02 15:04:05", updatedAtStr)
		if err != nil {
			logger.Warn("解析任务更新时间失败: %v", err)
			task.UpdatedAt = time.Now()
		}

		tasks = append(tasks, &task)
	}

	logger.Info("成功查询到 %d 个任务 (项目ID: %d)", len(tasks), projectID)
	return tasks, nil
}
